// #pragma once

// #include <iostream>
// #include <string>
// #include <functional>
// #include <pthread.h>

// namespace ThreadTest
// {
//     template <typename T>
//     using func_t = std::function<void(T &)>;

//     template <typename T>
//     class Thread
//     {
//     private:
//         // 回调函数
//         void Excute()
//         {
//             _func(_td);
//         }

//     public:
//         Thread(const std::string &thread_name, func_t<T> func, T &td)
//             : _tid(0), _func(func), _thread_name(thread_name), _isrunning(false), _td(td), _stop(false)
//         {
//         }

//         ~Thread()
//         {
//         }

//         // 线程执行函数
//         static void *threadrountine(void *args)
//         {
//             Thread *self = static_cast<Thread *>(args);
//             self->Excute();
//             return nullptr;
//         }

//         // 线程启动
//         bool Start()
//         {
//             int n = pthread_create(&_tid, nullptr, threadrountine, this);
//             // 成功返回0，进入if
//             if (n == 0)
//             {
//                 _isrunning = true;
//                 return true;
//             }
//             else
//                 return false;
//         }

//         // 分离线程
//         void Detach()
//         {
//             if (!_stop)
//             {
//                 _stop = true;
//                 pthread_detach(_tid);
//             }
//         }

//         // 回收线程
//         bool Join()
//         {
//             if (!_isrunning)
//                 return true;
//             int n = pthread_join(_tid, nullptr);
//             if (n == 0)
//             {
//                 _isrunning = false;
//                 return true;
//             }
//             return false;
//         }

//         // 线程名
//         std::string name()
//         {
//             return _thread_name;
//         }

//     private:
//         std::string _thread_name;
//         func_t<T> _func;
//         pthread_t _tid;
//         bool _isrunning;
//         bool _stop;
//         T _td;
//     };
// }

// // #ifndef __THREAD_HPP__
// // #define __THREAD_HPP__

// // #include <iostream>
// // #include <string>
// // #include <unistd.h>
// // #include <functional>
// // #include <pthread.h>

// // namespace ThreadModule
// // {
// //     template<typename T>
// //     using func_t = std::function<void(T&, std::string name)>;
// //     // typedef std::function<void(const T&)> func_t;

// //     template<typename T>
// //     class Thread
// //     {
// //     public:
// //         void Excute()
// //         {
// //             // std::cout << _threadname << std::endl;
// //             _func(_data, _threadname);
// //         }
// //     public:
// //         Thread(func_t<T> func, T &data, std::string name="none-name")
// //             : _func(func), _data(data), _threadname(name), _stop(true)
// //         {}
// //         static void *threadroutine(void *args) // 类成员函数，形参是有this指针的！！
// //         {
// //             Thread<T> *self = static_cast<Thread<T> *>(args);
// //             self->Excute();
// //             return nullptr;
// //         }
// //         bool Start()
// //         {
// //             int n = pthread_create(&_tid, nullptr, threadroutine, this);
// //             if(!n)
// //             {
// //                 _stop = false;
// //                 return true;
// //             }
// //             else
// //             {
// //                 return false;
// //             }
// //         }
// //         void Detach()
// //         {
// //             if(!_stop)
// //             {
// //                 pthread_detach(_tid);
// //             }
// //         }
// //         void Join()
// //         {
// //             if(!_stop)
// //             {
// //                 pthread_join(_tid, nullptr);
// //             }
// //         }
// //         std::string name()
// //         {
// //             return _threadname;
// //         }
// //         void Stop()
// //         {
// //             _stop = true;
// //         }
// //         ~Thread() {}

// //     private:
// //         pthread_t _tid;
// //         std::string _threadname;
// //         T &_data;  // 为了让所有的线程访问同一个全局变量
// //         func_t<T> _func;
// //         bool _stop;
// //     };
// // } // namespace ThreadModule

// // #endif

//teahcher code
#pragma once

#include <iostream>
#include <string>
#include <functional>
#include <pthread.h>

// 设计方的视角
//typedef std::function<void()> func_t;
template<class T>
using func_t = std::function<void(T&)>;

template<class T>
class Thread
{
public:
    Thread(const std::string &threadname, func_t<T> func, T &data)
    :_tid(0), _threadname(threadname), _isrunning(false), _func(func), _data(data)
    {}

    static void *ThreadRoutine(void *args) // 类内方法，
    {
        // (void)args; // 仅仅是为了防止编译器有告警
        Thread *ts = static_cast<Thread *>(args);

        ts->_func(ts->_data);

        return nullptr;
    }

    bool Start()
    {
        int n = pthread_create(&_tid, nullptr, ThreadRoutine, this/*?*/);
        if(n == 0) 
        {
            _isrunning = true;
            return true;
        }
        else return false;
    }

    bool Join()
    {
        if(!_isrunning) return true;
        int n = pthread_join(_tid, nullptr);
        if(n == 0)
        {
            _isrunning = false;
            return true;
        }
        return false;
    }
    std::string ThreadName()
    {
        return _threadname;
    }
    
    bool IsRunning()
    {
        return _isrunning;
    }
    ~Thread()
    {}
private:
    pthread_t _tid;
    std::string _threadname;
    bool _isrunning;
    func_t<T> _func;
    T _data;
};